import { any } from "../../../core/logic";
import { Engine } from "../../../Engine";
import { Pass } from "../Pass";
import { Effect, EffectType } from "./Effect";
import { sharp_vert } from "./shaders/sharp_vert";
import { sharp_frag } from "./shaders/sharp_frag";
import { SharpComputer } from "../compute/SharpComputer";
/**
 * 全局阴影，提升场景的阴暗明亮对比度。
 * @class
 * @memberof w.effects
 */
class Sharp extends Effect {
  /**
   * @constructor
   * @param {*} opts
   * @param {Number} opts.maxDistance 三维平面内周围半径范围。
   * @param {Number} opts.maxPixel 二位平面内周围最大范围
   * @param {Number} opts.darkFactor 黑色因子
   */
  constructor(opts = {}) {
    super(opts);
    this.type = EffectType.Sharp;
    this.sampler = Engine.instance.device.createSampler({
      magFilter: "linear", //nearest linear
      minFilter: "linear",
    });
    this.computer = new SharpComputer(opts)
    this.addCompute(this.computer)
    this.initPipeLine();
    this.sharpFactor = any(opts.sharpFactor, 0.5);
    this.sharpPreBlurFactor = any(opts.sharpPreBlurFactor, 0.6);
  }
  set sharpFactor(v) {
    this._sharpFactor = v;
    this.computer.sharpFactor = v
    return this;
  }
  get sharpFactor() {
    return this._sharpFactor;
  }
  set sharpPreBlurFactor(v) {
    this._sharpPreBlurFactor = v;
    this.computer.sharpPreBlurFactor = v
    return this;
  }
  get sharpPreBlurFactor() {
    return this._sharpPreBlurFactor;
  }

  initPipeLine() {
    this.pipeLine = Engine.instance.device.createRenderPipeline({
      label: "Sharp Pipline",
      layout: `auto`,
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: sharp_vert,
        }),
        entryPoint: "main",
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: sharp_frag,
        }),
        entryPoint: "main",
        targets: [
          {
            format: Engine.instance.format,
          },
        ],
      },
      primitive: {
        topology: "triangle-list",
        cullMode: "back",
        frontFace: "ccw",
      },
    });
  }
  initBindGroup() {
    const sharpTex = this.computer.sharpTex;
    if (this.bindGroup && this.bindGroup.id != sharpTex.id) {
      this.bindGroup = null;
    }
    if (!this.bindGroup) {
      this.bindGroup = Engine.instance.device.createBindGroup({
        label: "Sharp bindGroup",
        layout: this.pipeLine.getBindGroupLayout(0),
        entries: [
          {
            binding: 0,
            resource: this.sampler,
          },
          {
            binding: 1,
            resource: sharpTex.view,
          },
        ],
      });
      this.bindGroup.id = sharpTex.id;
    }
    return this.bindGroup
  }
  onRender(commandEncoder) {
    //执行帧渲染
    const pass = super.onRender(commandEncoder);
    const renderPass = commandEncoder.beginRenderPass(pass);
    renderPass.setPipeline(this.pipeLine);
    let bindGroup = this.initBindGroup();
    renderPass.setBindGroup(0, bindGroup);
    renderPass.draw(3);
    renderPass.end();
  }
  getDescript() {
    if (this._descript) {
      if (
        this._descript.size[0] !== Engine.instance.size[0] ||
        this._descript.size[1] !== Engine.instance.size[1]
      ) {
        this._descript = null;
      } else {
        this._descript.colorAttachments[0].view = Pass.instance().writeAttach.view;
      }
    }
    if (!this._descript) {
      this._descript = {
        colorAttachments: [
          {
            view: Pass.instance().writeAttach.view,
            loadOp: "clear",
            clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
            storeOp: "store",
          },
        ],
      };
      this._descript.size = Engine.instance.size;
    }
    return this._descript;
  }
}
export { Sharp };
